package com.dj.controller;

import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import com.dj.service.JcbgService;
import com.dj.util.CrudOperationUtil;
import org.hl7.fhir.dstu3.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * @author cyf
 * @description 患者
 * @create 2018-06-27 10:54
 **/

@Controller
public class JcbgController {

    private static final Logger logger = LoggerFactory.getLogger(JcbgController.class);

    @Autowired
    private JcbgService jcbgService;


    /**
     * 创建
     *
     * @param bundle
     * @return
     */
    @Create
    @Transactional
    public MethodOutcome create(@ResourceParam Bundle bundle) {
        long startTime = System.currentTimeMillis();
        logger.info("Bundle create start!!!");
        //判断 identifier
        if (bundle.getEntryFirstRep().isEmpty()) {
            //定义填充操作结果
            throw new UnprocessableEntityException("No identifier supplied");
        }
        Boolean flag = false;
        try {
            String[] subject = ((Composition) bundle.getEntry().get(0).getResource()).getSubject().getReference().split("/");
            String[] encounter = ((Composition) bundle.getEntry().get(0).getResource()).getEncounter().getReference().split("/");
            String patientId = subject[subject.length - 1];
            String encounterId = encounter[encounter.length - 1];
            logger.info("The Bundle relation patientId is {}, encounterId is {}",patientId,encounterId);
            flag = jcbgService.isExist(patientId, encounterId);
        } catch (Exception e) {
            logger.error("error ", e);
        }
        if (flag) { //执行 create
            IdType idType = jcbgService.saveBundle(bundle);
            logger.info("The bundle save success");
            return CrudOperationUtil.getMethodOutcome(idType, startTime);
        } else { // 关联患者不存在
            logger.info("This ID does not exist.");
            return CrudOperationUtil.getEmptyMethodOutcome(1);//0 - patient ;1 - encounter
        }
    }

    /**
     * 更新
     *
     * @param theId
     * @param bundle
     * @return
     */
    @Update
    @Transactional
    public MethodOutcome update(@IdParam IdType theId, @ResourceParam Bundle bundle) {
        long startTime = System.currentTimeMillis();
        logger.info("Bundle update start!!!");

        String id = theId.getIdPart();
        String versionId = theId.getVersionIdPart();
        //String currentVersion = "1"; // populate this with the current version

        IdType idType = jcbgService.updateBundle(id, versionId, bundle);
        logger.info("Bundle update end!!!");
        String updateVersion = String.valueOf(Long.valueOf(idType.getVersionIdPart()) - 1L);
        if (versionId != null && !versionId.equals("")) {
            if (id.equals(idType.getIdPart()) && versionId.equals(updateVersion)) {
                return CrudOperationUtil.getMethodOutcome(idType, startTime);
            } else {
                throw new ResourceVersionConflictException("Expected version " + versionId);
            }
        } else {
            return CrudOperationUtil.getMethodOutcome(idType, startTime);
        }
    }

    /**
     * 查询id 历史
     *
     * @param idType
     * @return
     */
    @Read(version = true)
    public Bundle getByIdOrVersion(@IdParam IdType idType) {
        logger.info("Bundle getByIdOrVersion  start!!!, idType={}", idType);

        Bundle bundle = new Bundle();
        Meta meta = new Meta();
        String id = idType.getIdPart();

        if (idType.hasVersionIdPart()) {
            //历史记录
            String version = idType.getVersionIdPart();
            logger.info("Query historical version records, the id is {}, version is {}",id ,version);
            Date date = jcbgService.getHistoryLastUpdatTime(id, version);
            if (date != null) {
                meta.setLastUpdated(date);
                bundle = jcbgService.getByIdAndVersion(id, version);
            } else {
                logger.info("Error, This historical version does not exist, the version is {}",version);
            }
        } else {
            logger.info("Query the current version record, the id is {}" ,id);
            //当前记录
            meta.setLastUpdated(jcbgService.getLastUpdatTime(id));
            bundle = jcbgService.getById(id);
        }
        if (!bundle.isEmpty()) {
            bundle.setMeta(meta);
        } else {
            //bundle = CrudOperationUtil.getQueryEmpty(bundle,"Bundle/"+id);
        }
        return bundle;
    }

    /**
     * 查询所有历史记录
     *
     * @param theId
     * @return
     */
    @History(type = Bundle.class)
    public List<Bundle> getBundleHistory(@IdParam IdType theId) {
        logger.info("Bundle getAllBundleHistory start!!!, theId={}", theId);
        String id = theId.getIdPart();
        return jcbgService.getAllBundleById(id);
    }

    /*检查项目*/
    /*<code>
        <coding>
            <system value="http://loinc.org"/>
            <code value="80859-2"/>
            <display value="心脏彩色多普勒超声"/>
        </coding>
    </code>*/

    /**
     * code
     *     检查报告通过检查项目名称查询方式为：
     *      /Bundle?composition.entry.code:text=心脏彩色多普勒超声或者
     *      /Bundle?composition.entry:Observation.code:text=心脏彩色多普勒超声
     * @param code
     * @return
     */

    @Search()
    //composition.entry:Observation.code:text
    public List<Bundle> searchByCode(@RequiredParam(name = "composition.entry:Observation.code:text") StringParam code) {
        logger.info("Bundle searchByCode start!!!, code = {}", code);
        return jcbgService.getByItemCode(code);
    }


    /**
     * 删除
     *
     * @param theId
     * @return
     */
    @Delete(type = Bundle.class)
    @Transactional
    public MethodOutcome delete(@IdParam IdType theId) {
        long startTime = System.currentTimeMillis();
        logger.info("Bundle delete start!!!, theId={}", theId);
        return CrudOperationUtil.delete(theId, jcbgService::deleteBundle, startTime);


    }


}
